package io.renren.common.utils;

import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder.BorderSide;
import org.springframework.web.multipart.MultipartFile;

import io.renren.common.entity.ExcelEntity;

public class ExcelUtils {
    private final static String EXCEL_2003 = ".xls"; // 2003- 版本的excel
	private final static String EXCEL_2007 = ".xlsx"; // 2007+ 版本的excel

    // 导出 start
    public static void exportExcel(HttpServletResponse response, String fileName, ExcelEntity data) throws Exception {
        // 告诉浏览器用什么软件可以打开此文件
        response.setHeader("content-Type", "application/vnd.ms-excel");
        // 下载文件的默认名称
        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(fileName, "utf-8"));
        exportExcel(data, response.getOutputStream());
    }

    public static void exportExcel(ExcelEntity data, OutputStream out) throws Exception {

        XSSFWorkbook wb = new XSSFWorkbook();
        try {
            String sheetName = data.getName();
            if (null == sheetName) {
                sheetName = "Sheet1";
            }
            XSSFSheet sheet = wb.createSheet(sheetName);
            writeExcel(wb, sheet, data);

            wb.write(out);
        } catch(Exception e){
            e.printStackTrace();
        }finally{
            //此处需要关闭 wb 变量
            out.close();
        }
	}
	
    private static void writeExcel(XSSFWorkbook wb, Sheet sheet, ExcelEntity data) {

        int rowIndex = 0;

        rowIndex = writeTitlesToExcel(wb, sheet, data.getTitles());
        writeRowsToExcel(wb, sheet, data.getRows(), rowIndex);
        autoSizeColumns(sheet, data.getTitles().size() + 1);

    }

    private static int writeTitlesToExcel(XSSFWorkbook wb, Sheet sheet, List<String> titles) {
        int rowIndex = 0;
        int colIndex = 0;

        Font titleFont = wb.createFont();
        titleFont.setFontName("simsun");
        //titleFont.setBoldweight(Short.MAX_VALUE);
        // titleFont.setFontHeightInPoints((short) 14);
        titleFont.setColor(IndexedColors.BLACK.index);

        XSSFCellStyle titleStyle = wb.createCellStyle();
        titleStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        titleStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        titleStyle.setFillForegroundColor(new XSSFColor(new Color(182, 184, 192)));
        titleStyle.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        titleStyle.setFont(titleFont);
        setBorder(titleStyle, BorderStyle.THIN, new XSSFColor(new Color(0, 0, 0)));

        Row titleRow = sheet.createRow(rowIndex);
        // titleRow.setHeightInPoints(25);
        colIndex = 0;

        for (String field : titles) {
            Cell cell = titleRow.createCell(colIndex);
            cell.setCellValue(field);
            cell.setCellStyle(titleStyle);
            colIndex++;
        }

        rowIndex++;
        return rowIndex;
    }

    private static int writeRowsToExcel(XSSFWorkbook wb, Sheet sheet, List<List<Object>> rows, int rowIndex) {
        int colIndex = 0;

        Font dataFont = wb.createFont();
        dataFont.setFontName("simsun");
        // dataFont.setFontHeightInPoints((short) 14);
        dataFont.setColor(IndexedColors.BLACK.index);

        XSSFCellStyle dataStyle = wb.createCellStyle();
        dataStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);
        dataStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        dataStyle.setFont(dataFont);
        setBorder(dataStyle, BorderStyle.THIN, new XSSFColor(new Color(0, 0, 0)));

        for (List<Object> rowData : rows) {
            Row dataRow = sheet.createRow(rowIndex);
            // dataRow.setHeightInPoints(25);
            colIndex = 0;

            for (Object cellData : rowData) {
                Cell cell = dataRow.createCell(colIndex);
                if (cellData != null) {
                    cell.setCellValue(cellData.toString());
                } else {
                    cell.setCellValue("");
                }

                cell.setCellStyle(dataStyle);
                colIndex++;
            }
            rowIndex++;
        }
        return rowIndex;
    }

    private static void autoSizeColumns(Sheet sheet, int columnNumber) {

        for (int i = 0; i < columnNumber; i++) {
            int orgWidth = sheet.getColumnWidth(i);
            sheet.autoSizeColumn(i, true);
            // int newWidth = (int) (sheet.getColumnWidth(i) + 100);	// 列宽超过255 错误
            // if (newWidth > orgWidth) {
            //     sheet.setColumnWidth(i, newWidth);
            // } else {
            //     sheet.setColumnWidth(i, orgWidth);
			// }
			if(orgWidth<255*256){	// 解决方法一
                sheet.setColumnWidth(i, orgWidth < 3000 ? 3000 : orgWidth);    
            }else{
                sheet.setColumnWidth(i,6000 );
			}
			// if (orgWidth > 255)  // 解决办法二 还是有问题
			// {
			// 	orgWidth = 255;
			// }
			// //设置列宽
			// sheet.setColumnWidth(i, (orgWidth + 1) * 256);
        }
    }

    private static void setBorder(XSSFCellStyle style, BorderStyle border, XSSFColor color) {
        style.setBorderTop(border);
        style.setBorderLeft(border);
        style.setBorderRight(border);
        style.setBorderBottom(border);
        style.setBorderColor(BorderSide.TOP, color);
        style.setBorderColor(BorderSide.LEFT, color);
        style.setBorderColor(BorderSide.RIGHT, color);
        style.setBorderColor(BorderSide.BOTTOM, color);
    }
    // 导出 end

    // 导入 start
    /**
	 * 功能描述:创建工作簿
	 *
	 * @author grm
	 * @since 2020年1月28日
	 * @param file 文件
	 * @return workbook
	 */
	public static Workbook createWorkbook(MultipartFile file) {
		InputStream inputStream;
		Workbook workbook = null;
		try {
			if(file.isEmpty()) {
				R.error("file is empty!");
				return null;
			}
			inputStream = file.getInputStream();
			String fileType = getFileType(file);
			if (EXCEL_2003.equals(fileType)) {
				workbook = new HSSFWorkbook(inputStream);
			} else if (EXCEL_2007.equals(fileType)) {
				workbook = new XSSFWorkbook(inputStream);
			} else {
				R.error("file is not excel!");
				return null;
			}
		} catch (IOException e) {
			R.error(e.getMessage());
		}
		return workbook;
	}
	
	/**
	 * 功能描述:判断是否是空行
	 *
	 * @author grm
	 * @since 2020年1月28日
	 * @param row 行
	 * @return boolean
	 */
	public static boolean isEmptyRow(Row row) {
		if (row == null || row.toString().isEmpty()) {
			return true;
		} else {
			Iterator<Cell> it = row.iterator();
			boolean isEmpty = true;
			while (it.hasNext()) {
				Cell cell = it.next();
				if (cell.getCellType() != Cell.CELL_TYPE_BLANK) {
					isEmpty = false;
					break;
				}
			}
			return isEmpty;
		}
	}

	/**
	 * 功能描述:判断是不是excel文件
	 *
	 * @author grm
	 * @since 2020年1月28日
	 * @param file 文件
	 * @return boolean
	 */
	public static boolean isExcel(MultipartFile file) {
		String fileType = getFileType(file);
		if ((!EXCEL_2003.equals(fileType)) && (!EXCEL_2007.equals(fileType))) {
			R.error("file is not excel!");
			return false;
		}
		return true;
	}

	/**
	 * 功能描述:获取文件类型/后缀
	 *
	 * @author grm
	 * @since 2020年1月28日
	 * @param file 文件
	 * @return fileType
	 */
	public static String getFileType(MultipartFile file) {
		String originalFilename = file.getOriginalFilename();
		return (originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length())).toLowerCase();
	}

	/**
	 * 处理类型
	 * 
	 * @param cell
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static String getVal(Cell cell) {
		if (null != cell) {
			switch (cell.getCellType()) {
			case XSSFCell.CELL_TYPE_NUMERIC: // 数字
				double dou = cell.getNumericCellValue();
				NumberFormat nf = NumberFormat.getInstance();
				String str = nf.format(dou);
				if (str.indexOf(",") >= 0) {
					// 这种方法对于自动加".0"的数字可直接解决
					// 但如果是科学计数法的数字就转换成了带逗号的，例如：12345678912345的科学计数法是1.23457E+13
					// 经过这个格式化后就变成了字符串“12,345,678,912,345”，这也并不是想要的结果，所以要将逗号去掉
					str = str.replace(",", "");
				}
				return str;
			case XSSFCell.CELL_TYPE_STRING: // 字符串
				return cell.getStringCellValue() + "";
			case XSSFCell.CELL_TYPE_BOOLEAN: // Boolean
				return cell.getBooleanCellValue() + "";
			case XSSFCell.CELL_TYPE_FORMULA: // 公式
				try {
					if (HSSFDateUtil.isCellDateFormatted(cell)) {
						Date date = cell.getDateCellValue();
						return (date.getYear() + 1900) + "-" + (date.getMonth() + 1) + "-" + date.getDate();
					} else {
						return String.valueOf((int) cell.getNumericCellValue());
					}
				} catch (IllegalStateException e) {
					return String.valueOf(cell.getRichStringCellValue());
				}
			case XSSFCell.CELL_TYPE_BLANK: // 空值
				return "";
			case XSSFCell.CELL_TYPE_ERROR: // 故障
				return "";
			default:
				return "未知类型   ";
			}
		} else {
			return "";
		}
    }

    // /**
	//  * 功能描述:导入excel数据到二维数组
	//  *
	//  * @author grm
	//  * @since 2020年1月28日
	//  * @param file 文件
	//  * @return list
	//  */
	// public static List<List<String>> importExcel(MultipartFile file) {
	// 	List<List<String>> list = new ArrayList<>();
	// 	Workbook workbook = ExcelUtils.createWorkbook(file);
	// 	if (workbook != null) {
	// 		// 获取工作表
	// 		Sheet sheet = workbook.getSheetAt(0);
	// 		// 获取sheet中第一行行号
	// 		int firstRowNum = sheet.getFirstRowNum();
	// 		// 获取sheet中最后一行行号
	// 		int lastRowNum = sheet.getLastRowNum();
	// 		// 循环插入数据
	// 		for (int i = firstRowNum + 1; i <= lastRowNum; i++) { // 标题的下一行开始
	// 			Row row = sheet.getRow(i);
	// 			if (ExcelUtils.isEmptyRow(row) == false) {
                  
	// 				List<String> res = HandleRow(row);
	// 				list.add(res);
	// 			}
	// 		}
	// 	}
	// 	return list;
    // }
    
    // public static List<String> HandleRow(Row row) {
    //     List<String> res = new ArrayList<>();

    //     return res;
    // }

    // 导出 end
}